// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-8-20

#ifndef __COMROOT_H__
#define __COMROOT_H__

#pragma once


//##ModelId=44C4B5F702AF
class CJoyComDefRoot
{
public:
	//##ModelId=44C4B5F702B0
    virtual ~CJoyComDefRoot()
    {
    };
};

//##ModelId=44C4B5F702B2
template<typename SBaseType, typename IBaseFace, const IID& IID_IBaseFace=__uuidof(IBaseFace)>
class CJoyComRoot : public SBaseType, public IBaseFace
{
protected:
	//##ModelId=44C4B5F702C4
    LONG    m_lRefCount;
public:
	//##ModelId=44C4B5F702CE
    CJoyComRoot() 
    { 
        m_lRefCount = 1;
    }
	//##ModelId=44C4B5F702CF
    virtual ~CJoyComRoot()
    {
    }
	//##ModelId=44C4B5F702D1
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject)
    {
		if (ppvObject == NULL)
		{
			return E_POINTER;
		}
        if (riid == IID_IUnknown)
        {
            // use IBaseFace* here to avoid ambiguous conversions.
           *ppvObject = static_cast<IBaseFace*>(this);
        }
        else if (riid == IID_IBaseFace)
        {
            *ppvObject = static_cast<IBaseFace*>(this);
        }
        else
        {
            return E_NOINTERFACE;
        }
        
        reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
        return S_OK;
    }
	//##ModelId=44C4B5F702D5
    virtual ULONG STDMETHODCALLTYPE AddRef()
    {
        return _InterlockedIncrement(&m_lRefCount);
    }
	//##ModelId=44C4B5F702D7
    virtual ULONG STDMETHODCALLTYPE Release()
    {
        if (_InterlockedDecrement(&m_lRefCount) == 0)
        {
            delete this;
            return 0;
        }
        return m_lRefCount;
    }
    template<class Q>
    HRESULT STDMETHODCALLTYPE QueryInterfaceT(Q** pp)
    {
    	return QueryInterface(__uuidof(Q), (void **)pp);
    }
};

#endif  // __COMROOT_H__
